Overblog
Seguir este blog Administration + Create my blog
10 febrero 2014 1 10 /02 /febrero /2014 09:26

Hola hoy día vamos a tener unos temas que nos van a ayudar a manejar mejor nuestro código en Ruby, también estos temas son parte de la programación orientada a objetos.

 

Módulos

 

Un módulo nos permite agrupar generalmente clases y funciones o subrutinas, para poder utilizarlos posteriormente, se declara con module, el nombre de módulo debe empezar con maúsculas y se termina con un end, en el medio debe estar nuestro código:

 

irb(main):350:0> module Herramientas

irb(main):351:1>  VERSION = 1.1

irb(main):352:1>  def Herramientas.sumar a, b

irb(main):353:2>   a + b

irb(main):354:2>  end

irb(main):355:1>  def self.restar a, b

irb(main):356:2>   return a - b

irb(main):357:2>  end

irb(main):358:1> end

=> nil

 

Bueno en este ejemplo vemos en la linea 350 que se ha declarado el módulo "Herramientas" con el uso de "module", luego en la linea 351 se ha creado una constante VERSION, luego vemos que se ha creado un método "sumar", pero observamos que esta escrito como Herramientas.sumar, osea tiene el nombre del módulo mas un punto y seguidamente del método, esto indica que ese método es usable directamente desde el módulo; Acto seguido vemos en la linea 355 que se crea el método restar, pero observamos que hay un "self." ese self es como un reemplazo de Herramientas (para no tener que escribir el nombre del módulo) y es casi lo mismo que haber escrito "Herramientas.restar" pero hay que tener cuidado ya que self cambia de acuerdo al contexto del escenario, por lo que solo funcionará cuando lo llamemos dentro de su módulo, vemos en la línea 356 el uso de "return" pero es opcional, puede haber quedado simplemente como a - b.

 

Para usar el módulo directamente, hacemos lo siguiente:

 

irb(main):359:0> Herramientas.sumar 5, 2

=> 7

irb(main):360:0> Herramientas.restar 5, 2

=> 3

irb(main):361:0> Herramientas::VERSION

=> 1.1

irb(main):362:0> Herramientas::restar 5, 2

=> 3

 

Vemos que estamos usando los métodos sumar y restar directamente desde el módulo Herramientas, pero en la línea 361 vemos un operador nuevo, los cuatro puntos :: este operador nos sirve para accesar a las constantes, métodos, clases y otros módulos. Pero solo podemos hacer eso desde módulos o clases.

 

Herencia

 

En Ruby, el creador de este lenguaje ha preferido, por temas de diseño y practicidad, utilizar la herencia simple y usar MixIN para reemplazar la herencia múltiple, nos asegura que nos quita un dolor de cabeza 

 

Para realizar la herencia simplemente se usa el símbolo < (menor que) y este símbolo " < " se debe usar al declarar una nueva clase:

 

irb(main):367:0> class Lobo

irb(main):368:1>  def aullar

irb(main):369:2>   "Auuuuuu"

irb(main):370:2>  end

irb(main):371:1> end

=> nil

irb(main):372:0> class Perro < Lobo

irb(main):373:1>  def ladrar

irb(main):374:2>   "Guau!"

irb(main):375:2>  end

irb(main):376:1> end

=> nil

irb(main):377:0> chihuahua = Perro.new

=> #<Perro:0x000000044d8e70>

irb(main):378:0> chihuahua.ladrar

=> "Guau!"

irb(main):379:0> chihuahua.aullar

=> "Auuuuuu"

 

Como podemos ver, se ha creado una clase Lobo que tiene el método aullar, luego en la línea 372, hemos creado la clase Perro, pero esta "hereda" de la clase Lobo, la clase perro tiene solamente el método ladrar, pero al heredar de su ancestro Lobo, entonces tambien va a poder "aullar", osea utilizar el método aullar de la clase Lobo de la cual ha heredado, por eso hemos instanciado un Chihuaha de la clase Perro, pero este Chihuahua puede ladrar y también puede aullar (por herencia, se puede decir que Perro es una subclase de Lobo).

 

irb(main):381:0> chihuahua.class

=> Perro

irb(main):384:0> chihuahua.instance_of? Perro

=> true

irb(main):385:0> chihuahua.instance_of? Lobo

=> false

irb(main):386:0> chihuahua.kind_of? Lobo

=> true

irb(main):387:0> chihuahua.kind_of? Perro

=> true

irb(main):388:0> chihuahua.is_a? Perro

=> true

irb(main):389:0> chihuahua.is_a? Lobo

=> true

irb(main):433:0> Perro.superclass

=> Lobo

 

Como se puede ver, aqui hay unos métodos interesantes, en la linea 381 preguntamos de que clase es el chihuahua y nos dice que es un Perro, luego en la 384 le preguntamos si este chihuahua ¿es una instancia de Perro? (instance_of) y nos dice que si, le preguntamos en la 385 si ¿es una instancia de Lobo? y nos dice que no, pero en la 386 le preguntamos si el chihuahua ¿es una especie o tipo de lobo? (kind_of) y nos dice que sí, ya que el Perro es una subclase de Lobo, así que el Perro es una especie de Lobo (por increible que sea), ahora en las líneas 388 y 389 el método is_a? es un sinónimo de kind_of?, es decir son lo mismo; también en la línea 433 el superclass devuelve cual es la clase padre de la clase Perro.

 

MixIN (reemplazo de herencia múltiple)

 

Bueno ahora bien lo bueno, el MixIN es para poder utilizar otros módulos (que pueden contener otras clases y/o modulos) dentro de una clase o módulo, de tal manera que se reutiliza funcionalidad. Ahora veamos el módulo anterior:

 

irb(main):395:0> module Herramientas

irb(main):396:1>  VERSION = 1.1

irb(main):397:1>  def Herramientas.sumar a, b

irb(main):398:2>   a + b

irb(main):399:2>  end

irb(main):400:1>  def self.restar a, b

irb(main):401:2>   return a - b

irb(main):402:2>  end

irb(main):403:1>  def multiplicar

irb(main):404:2>    "no implementado"

irb(main):405:2>  end

irb(main):406:1> end

=> nil

 

Hemos añadido el método multiplicar al módulo Herramientas (línea 403) pero observamos que simplemente es "def multiplicar" y no es "def self.multiplicar" ni "def Herramientas.multiplicar", lo cual significa que ese método solo se puede usar en una instancia; ¿Pero se puede crear una instancia de un módulo? la respuesta es no!, entonces viene otra pregunta ¿en que momento se puede usar ese método si no se puede crear instancias de un módulo? o de otra manera ¿que sentido tiene definir métodos de instancia en el módulo si no se puede crear una instancia del módulo?, pues la solución es que solamente se puede si la "mezclamos", es decir, si realizamos el MixIN:

 

irb(main):413:0> class Calculadora

irb(main):414:1>  extend Herramientas

irb(main):415:1>  def que_realiza?

irb(main):416:2>   "operaciones"

irb(main):417:2>  end

irb(main):418:1> end

=> nil

irb(main):211:0> Calculadora.multiplicar

=> "no implementado"

 

Con el extend de la línea 414, nos sirve para que la clase Calculadora (no las instancias) pueda obtener los métodos de instancia del módulo (osea solo el "def multiplicar"), y en la línea 211 se ve que llamamos a ese método "multiplicar"; Pero desde la clase no podemos acceder directamente a la constante VERSION, y en una instancia de Calculadora tampoco podremos acceder a nada del módulo Herramientas, entonces para ello realizamos el MixIN:

 

Haciendo MixIN

 

irb(main):221:0> class Calculadora

irb(main):222:1>  extend Herramientas

irb(main):223:1>  include Herramientas

irb(main):224:1>  def que_realiza?

irb(main):225:2>   "operaciones"

irb(main):226:2>  end

irb(main):227:1> end

=> nil

irb(main):229:0> Calculadora::VERSION

=> 1.1

 

Ahora que se ha realizado el MixIN, la clase Calculadora ya puede acceder a la constante VERSION del módulo Herramientas, pero no solamente eso, sino que ahora las instancias de Calculadora pueden acceder:

 

irb(main):233:0> calc = Calculadora.new

=> #<Calculadora:0x2dd1c28>

irb(main):237:0> calc.multiplicar

=> "no implementado"

irb(main):238:0> calc.que_realiza?

=> "operaciones"

 

Ahora vamos a crear un módulo especial

 

irb(main):239:0> module Plus

irb(main):240:1>  def graficos_avanzados

irb(main):241:2>   true

irb(main):242:2>  end

irb(main):243:1> end

=> nil

 

Y vamos a crear una clase CalculadoraCientifica que heredará de Calculadora y hará un MixIN con el módulo Plus (hay que considerar que Calculadora tiene MixIN con Herramientas)

 

irb(main):261:0> class CalculadoraCientifica < Calculadora

irb(main):262:1>  include Plus

irb(main):263:1>  def que_realiza?

irb(main):264:2>   "realiza: #{super}, graficos"

irb(main):265:2>  end

irb(main):266:1> end

=> nil

irb(main):267:0> casio = CalculadoraCientifica.new

=> #<CalculadoraCientifica:0x30645d8>

irb(main):268:0> casio.que_realiza?

=> "realiza: operaciones, graficos"

irb(main):269:0> casio.graficos_avanzados

=> true

irb(main):270:0> casio.multiplicar

=> "no implementado"

 

Como se puede ve en la linea 262 hemos hecho un MixIN con Plus, y hemos obtenidos las funcionalidades de Plus (los métodos de instancia), ahora en la línea 264 se ve que estamos devolviendo una cadena de texto o string, y usamos el #{} ("michi" o numeral y llaves) que sirven para reemplazar por alguna variable en su interior, y en el interior usamos la palabra clave "super" que significa que va a utilizar el método "que_realiza?" pero de la clase padre Calculadora, luego como esta devuelve un string "operaciones" y reemplazando obtenemos "realiza: operaciones, graficos"; luego también heredamos los métodos MixIN de Calculadora del módulo Herramientas como el método de instancia "multiplicar".

 

Ahora también podemos usar el método:

 

irb(main):271:0> CalculadoraCientifica.ancestors

=> [CalculadoraCientifica, Plus, Calculadora, Herramientas, Object, Kernel, BasicObject]

 

Que nos devuelve un array conteniendo las clases y/o módulos que "arman" a la clase CalculadoraCientifica, empieza por la misma clase, luego el módulo Plus, luego la clase Calculadora y el módulo Herramientas, las otras clases Object, Kernel, BasicObject, son añadidas tanto por el lenguaje Ruby como por el IRB.

 

Es importante que primero Ruby buscará los métodos en su propia clase CalculadoraCientifica, si no lo encuentra proseguirá en buscar en Plus, si no lo encuentra proseguirá en buscar en Calculadora y luego en Herramientas.

 

Para las clases, el último método sobreescribe al primero, como se vió en la línea 264, se volvio a sobreescribir el método que_realiza? se debe considerar como concepto vertical de sobreescritura de métodos en herencias y MixIN.

 

Muy bien, culminamos este interesante capítulo, hasta aqui vamos con el capitulo 17 y sugiero que lo lean varias veces y practiquen ya que este tema es un pilar para los diversos frameworks y utilidades escritas en Ruby, el siguiente capítulo es el número 18, cualquier duda pueden comentar y sera absuelto, no tienes que registrarte ni realizar nada adicional para comentar, soy su amigo!.

Compartir este post
Repost0
4 febrero 2014 2 04 /02 /febrero /2014 21:30

Este tema es muy interesante y la verdad demasiado util, sin mas que decir, una expresión regular es aquel texto que nos sirve para realizar comparaciones, por lo general, contra otras cadenas de texto y ver si coinciden o no.

 

Se pueden usar como patrones, obtener datos y otros usos específicos. Practicamente es todo un pequeño mundo.

 

Comparación básica

 

Una expresión regular en Ruby va delimitado por dos slashes ( / / ) o barras diagonales que encierran un string de la siguiente manera /string/ por ejemplo vamos a crear una que nos sirva para detectar cadenas de texto que contengan la palabra bono.

 

irb(main):251:0> /bono/.class

=> Regexp

irb(main):252:0> /bono/.match "no hay bono"

=> #<MatchData "bono">

irb(main):253:0> /bono/.match "no hay nada"

=> nil

 

Como se puede ver, la expresión regular proviene de la clase Regexp, por lo que es un objeto y tiene métodos, usamos en la línea 252 el método match, el cual compara la expresión regular /bono/ contra la frase "no hay bono" y como esta frase contiene la expresión "bono" que buscamos, osea "coincide", entonces devuelve un objeto de la clase MatchData, en la línea 253 la expresión regular /bono/ no coincide con la frase "no hay nada" entonces al no existir "coincidencia" devuelve un nil.

 

irb(main):292:0> /bono/ =~ "no hay bono"

=> 7

irb(main):293:0> /bono/ =~ "no hay nada"

=> nil

 

Esta es otra forma de comparar con el operador " =~ " el cual, si existe coincidencia devuelve la posición en donde empieza la coincidencia mediante un número entero, caso contrario devuelve nil.

 

Ahora el resultado de este operador se puede conseguir mediante el objeto devuelto de la clase MatchData:

 

irb(main):294:0> /bono/.match("no hay bono").pre_match.length

=> 7

 

El objeto match tiene varios métodos entre ellos el pre_match y post_match, que devuelven la cadena de texto antes de la coincidencia y despues de la coincidencia respectivamente:

 

irb(main):295:0> /bono/.match("no hay bono, que pena").pre_match

=> "no hay "

irb(main):296:0> /bono/.match("no hay bono, que pena").post_match

=> ", que pena"

 

Captura de valores

 

Según la expresión regular, es posible capturar diversos valores de un determinado texto, por ejemplo las carácterísticas frases: "Juego de manos, juego de villanos", para poder capturar las palabras manos y villanos, podemos usar lo siguiente:

 

irb(main):300:0> expresion = /^Juego de (\w+), juego de (\w+)$/

=> /^Juego de (\w+), juego de (\w+)$/

irb(main):301:0> frase = "Juego de manos, juego de villanos"

=> "Juego de manos, juego de villanos"

irb(main):302:0> resultado = expresion.match frase

=> #<MatchData "Juego de manos, juego de villanos" 1:"manos" 2:"villanos">

irb(main):303:0> resultado.captures

=> ["manos", "villanos"]

irb(main):304:0> otra_frase = "Juego de manitos, juego de villanitos"

=> "Juego de manitos, juego de villanitos"

irb(main):305:0> resultado = expresion.match otra_frase

=> #<MatchData "Juego de manitos, juego de villanitos" 1:"manitos" 2:"villanitos">

irb(main):306:0> resultado.captures

=> ["manitos", "villanitos"]

 

Aquí tenemos varios casos, para comenzar solo mencionaré los mas importanes ya que las expresiones regulares tienen un amplio abanico de posibilidades.

 

En la linea 300 hemos colocado una expresion regular en la variable expresion, el contenido de la expresion regular es la siguiente; Después del primer delimitador " / ", luego viene el símbolo ^ que indica que la frase debe comenzar exactamente de esa manera "Juego de...", luego sigue una porción de la frase y nos encontramos con (\w+), estos son justamente lo que se captura, a detalle todo lo que esta en paréntesis " ( " y " ) " es capturado, dentro de lo capturado el \w significa que va a validar 1 sola letra, o número o puntuación, ahora el símbolo mas " + " significa que no sea 1 sola letra sino que sean varias (hasta que ya no se cumpla dicha especificación, como puede ser un espacio en blanco), luego realiza su primera captura, mas adelante hay otro (\w+) lo capturará y termina con un símbolo de dolar $, que significa que la frase debe terminar ahí y no debe haber nada más.

 

En la línea 303, usamos el método "captures" del objeto resultado (MatchData) y nos devuelve una matriz de los valores que han sido capturados.

 

En la línea 304 hacemos una variación a la frase y volvemos a capturar los valores en el 306, como verán existe una coincidencia y ahora nos muestra los nuevos valores capturados.

 

Bueno esto es solo una introducción a las expresiones regulares, existe mucho pero mucho por investigar en expresiones regulares y lo bueno es que ahorra un montón de líneas de código.

 

Muy bien, existen mucho mas cosas que se pueden hacer pero lo veremos en los proximos capitulos, hasta aqui vamos con el capitulo 16, el siguiente es el capitulo 17, cualquier duda pueden comentar y sera absuelto, no tienes que registrarte ni realizar nada adicional para comentar.

Compartir este post
Repost0
4 febrero 2014 2 04 /02 /febrero /2014 18:27

Este tema es muy pero muy importante, ya que nos permite tener practicamente una base de datos accesible de manera dinámica organizado en pares, para entenderlo voy a dar una definición pequeña:

 

Un hash es un grupo de valores donde se organizan por pares, donde existen los llamados llaves o "keys" y los valores respectivos asociados a esos "Keys", la sintaxis es la siguiente:

 

{llave1 => valor1, llave2 => valor2, llave3 => valor3} 

 

Las llaves pueden ser un simbolo, un numero, una letra o algun objeto compatible, los valores pueden ser un arreglo, otro hash, letras, numeros, booleans o cualquier objeto compatible, siempre deben estar en los signos de llaves " { " y " } " y el asignador es el operador =>, que genera un "par", ahora los pares deben estar separados por comas ","

 

Asignaciones

 

Un ejemplo:

 

irb(main):134:0> {1=>"as",2=>"bb"}

=> {1=>"as", 2=>"bb"}

 

Aquí le estamos diciendo que la llave 1 tiene el valor "as" y que la llave 2 tiene el valor "bb"

 

irb(main):139:0> mi_hash = {:edad => 2, :tipo => "perro"}

=> {:edad=>2, :tipo=>"perro"}

irb(main):140:0> mi_hash = {edad: 2, tipo: 'perro'}

=> {:edad=>2, :tipo=>"perro"}

 

En este ejemplo estamos diciendo que la llave :edad (del tipo simbolo) tiene el valor 2 y que la llave :tipo tiene el valor "perro", en la siguiente linea 140, estamos asignando las mismas llaves y valores, pero la sintaxis esta un poco mas resumida, el par ahora esta compuesto por los 2 puntos seguidos edad: y luego un espacio y seguido del valor 2 quedando "edad: 2", el unico inconveniente es que la llave siempre va a ser un simbolo y si encuentra alguna llave que no puede hacer la conversion va a darnos un error.

 

Tambien es posible combinar las sintaxis según la conveniencia:

 

irb(main):159:0> {s: "as",c: "bb", 2 => "cc"}

=> {:s=>"as", :c=>"bb", 2=>"cc"}

 

Como podemos observar, los 2 primeros pares tienen la sintaxis resumida y estan convirtiendo en string a la llave s y a la llave c, pero en el ultimo par, se usa la sintaxis tradicional y se tiene la llave 2 del tipo numero asignando el valor "cc" del tipo string o palabra o cadena de texto como quieran llamarle.

 

Consultando valores y pares

 

Podemos realizar consultas diversas consultas por ejemplo:

 

irb(main):160:0> mi_hash

=> {:edad=>2, :tipo=>"perro"}

irb(main):161:0> mi_hash.keys

=> [:edad, :tipo]

irb(main):162:0> mi_hash.values

=> [2, "perro"]

irb(main):163:0> mi_hash.first

=> [:edad, 2]

 

En la línea 161 estamos preguntando por medio del método keys, que nos indique cuantas "llaves" tiene el hash, y nos devuelve un arreglo que indica que tenemos 2 llaves (:edad y :tipo), luego en la línea 162 estamos preguntando los valores que tiene el hash, que tambien nos devuelve un arreglo, luego en el 163 le estamos indicando que nos devuelva el primer "par" y lo hace dándonos un arreglo.

 

Podemos consultar directamente por la llave, lo cual hace una verdadera búsqueda de base de datos

 

irb(main):165:0> mi_hash[:edad]

=> 2

irb(main):166:0> mi_hash[:tipo]

=> "perro"

 

Aquí nos devuelve directamente el valor que solicitamos en vase a la llave, y es aquí la utilidad real de un hash, la consulta se hace colocando la llave entre corchetes " [ " y " ] ".

 

Para poder saber que llave contiene un determinado valor, se puede utilizar el método key de la siguiente manera:

 

irb(main):169:0> mi_hash.key 2

=> :edad

irb(main):173:0> mi_hash.key "perro"

=> :tipo

 

En ambos casos, tanto la búsqueda por la llave como por el valor, si no lo encuentra, devolverá un nil

 

Otra forma de hacer lo mismo es poder invertir y realizar la busqueda

 

irb(main):186:0> mi_hash

=> {:edad=>2, :tipo=>"perro"}

irb(main):187:0> mi_hash.invert

=> {2=>:edad, "perro"=>:tipo}

irb(main):188:0> mi_hash.invert[2]

=> :edad

 

Utilizando el método invert, cambia cada llave por el valor y luego podemos hacer la consulta como si se tratara de una llave pero hay que tener cuidado con los valores que sean iguales en otras llaves, ya que al invertirlo solo tomará el primero de los pares que tengan ese valor por ejemplo:

 

irb(main):023:0> r= {j: 2,k: 2}

=> {:j=>2, :k=>2}

irb(main):024:0> r.invert

=> {2=>:k}

 

Se puede ver que solamente queda el ultimo par al momento de invertir el hash.

 

Como un hash puede contener otros hash, una forma sencilla de obtener el ultimo elemento es convertir el hash en arreglo y luego obtener el ultimo elemento del arreglo que seria el ultimo par del hash.

 

irb(main):196:0> mi_hash.to_a

=> [[:edad, 2], [:tipo, "perro"]]

irb(main):197:0> mi_hash.to_a.last

=> [:tipo, "perro"]

 

Hay que considerar que un hash puede almacenar otros hash y arreglos, con lo cual se puede volver trivial obtener el ultimo valor, por lo que Ruby no coloca el método last y nos obliga a realizar una lógica para obtener nuestro último valor segun nuestra necesidad.

 

Agregando pares

 

Podemos agregar más pares de manera sencilla, por ejemplo:

 

irb(main):200:0> mi_hash.store :color, :caramelo

=> :caramelo

irb(main):201:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo}

 

Usando el método store, podemos almacenar un nuevo par, otra forma tambien es con:

 

irb(main):203:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo}

irb(main):204:0> mi_hash[:habilidad] = 'ladrar mucho'

=> "ladrar mucho"

irb(main):205:0> mi_hash[:ventajas] = [:alto,:fuerte,:entrenado]

=> [:alto, :fuerte, :entrenado]

irb(main):206:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo, :habilidad=>"ladrar mucho", :ventajas=>[:alto, :fuerte, :entrenado]}

 

En la línea 204 ponemos el valor de la llave entre corchetes y luego con el operador = asignamos el valor de la nueva llave, en la línea 205 estamos agregando un par donde el valor es un arreglo.

 

Tambien es posible agregar mas valores de una sola vez, usando lo siguiente:

 

irb(main):203:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo}

irb(main):210:0> mi_hash = mi_hash.merge({ :nombre => :fido, :entrenado => true })

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo, :nombre=>:fido, :entrenado=>true}

irb(main):211:0> mi_hash = mi_hash.merge nombre: :fido, entrenado: true

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo, :nombre=>:fido, :entrenado=>true}

 

En este ejemplo se puede observar que hemos utilizado el método merge donde le asignamos un hash y mezcla en nuestro hash, tambien se ha de observar que en la linea 211 es lo mismo solo que se ha eliminado los paréntesis, los símbolos de llaves y se utiliza la sintaxis corta, ayudando todo esto a tener una visibilidad mucho más simple.

 

Eliminado pares

 

Para eliminar pares es muy sencillo, para ello podemos usar el método delete

 

irb(main):219:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo, :nombre=>:fido, :entrenado=>true}

irb(main):220:0> mi_hash.delete :entrenado

=> true

irb(main):221:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo, :nombre=>:fido}

 

Aquí hemos borrado por la llave :entrenado, ahora si queremos eliminar por el valor podemos usar:

 

irb(main):237:0> mi_hash

=> {:edad=>2, :tipo=>"perro", :color=>:caramelo, :nombre=>:fido}

irb(main):238:0> mi_hash.delete mi_hash.invert.delete 2

=> 2

irb(main):239:0> mi_hash

=> {:tipo=>"perro", :color=>:caramelo, :nombre=>:fido}

 

Donde en la línea 238 primero invertimos el hash, luego obtenemos la llave del valor 2 con el método delete (que tambien se pudo utilizar otro método que nos retorne la llave) acto seguido como ya tenemos la llave, el método delete del hash sin invertir eliminará el par.

 

Actualizando valores de los pares

 

Para actualizar se puede usar simplemente los métodos store y merge, también llamando la llave por medió de los corchetes, para actualizar las llaves se puede usar el invert pero hay que tener cuidado con los valores duplicados.

 

irb(main):244:0> mi_hash

=> {:tipo=>"perro", :color=>:caramelo, :nombre=>:fido}

irb(main):245:0> mi_hash.store :nombre, :canuto

=> :canuto

irb(main):246:0> mi_hash

=> {:tipo=>"perro", :color=>:caramelo, :nombre=>:canuto}

irb(main):247:0> mi_hash = mi_hash.merge nombre: :canito

=> {:tipo=>"perro", :color=>:caramelo, :nombre=>:canito}

irb(main):248:0> mi_hash[:nombre]=:tobi

=> :tobi

irb(main):249:0> mi_hash

=> {:tipo=>"perro", :color=>:caramelo, :nombre=>:tobi}

 

De la misma forma parecida a la que se agregaban pares y valores, para actualizarlos simplemente se reutiliza la llave o las llaves o pares que se desea actualizar, dando bastante flexibilidad.

 

Bueno hemos avanzado con este importante capitulo 15 y seguiremos con el capitulo 16, por favor dudas y comentarios pueden hacerlo si ningún tipo de restriccion, si desean agradecer también, gracias y comenten.

 

Compartir este post
Repost0
4 febrero 2014 2 04 /02 /febrero /2014 17:08

Bueno este tema es bastante sencillo, en Ruby se puede trabajar con Rangos que es una indicación de una cantidad de elementos, con ellos se pueden hacer muchas cosas:

 

Tipos de rangos

 

Incluyendo el último elemento

 

irb(main):001:0> 1..2

=> 1..2

irb(main):002:0> (1..2).class

=> Range

 

En este caso se puede ver que para indicar un rango se usa 2 puntos seguidos ( .. ) y en los extremos se ponen los valores, en este caso en la línea 1 se indica un rango del 1 hasta el 2 contando el 2, es decir que tenemos 2 elementos el 1 y el 2, luego para poder conocer las propiedades del rango, este debe encapsularse en paréntesis, porque sino sería trivial, si no le ponemos quedaría 1..2.class entonces Ruby entendería que deseamos crear un rango desde 1 hasta 2.class que sería Fixnum osea 1..Fixnum, lo cual daría un error, al encerrarlo en paréntesis tambien podemos colocar el Rango en una variable, ya que también el rango es un objeto.

 

Sin incluir el último elemento

 

Ahora hay que diferenciar del otro tipo de rango con 3 puntos:

 

irb(main):006:0> 1...2

=> 1...2

irb(main):007:0> (1...2).class

=> Range

 

Muy parecido al rango de 2 puntos, pero en este caso cuando se utilizan los 3 puntos no se cuenta el ultimo valor, por lo que tenemos de 1 hasta 1 que daría 1 solo elemento en el rango de 1...2.

 

Rangos por tipos

 

En Ruby tenemos un abanico de posibilidades para trabajar con rangos, por ejemplo con simbolos:

 

irb(main):011:0> :mama...:meme

=> :mama...:meme

irb(main):012:0> (:mama...:meme).class

=> Range

irb(main):013:0> (:mama...:meme).member? :mame

=> true

 

Explicando un poco, hemos creado un rango desde :mama hasta antes de :meme (no se cuenta :meme porque estamos usando los 3 puntos ( ... ) ), las propiedades de un rango son parecidos a los de un arreglo, tambien podemos usar el método " to_a " para convertirlo a arreglo

 

irb(main):042:0> (:mama...:meme).to_a.count

=> 2708

 

Aquí lo que se ha hecho es convertir el rango a un arreglo y contar con "count" con cuantas palabras cuenta ese rango y son 2708, que muy facilmente lo tenemos gracias a un rango de 1 sola línea de código.

 

Otro ejemplo con letras

 

irb(main):043:0> ('a'..'d').to_a

=> ["a", "b", "c", "d"]

 

Con números

 

irb(main):085:0> (1...4).to_a

=> [1, 2, 3]

 

Pero hay que tener cuidado con los decimales, no pueden ser convertibles a un arreglo (lamentablemente en nuestro sistema de numeración existe el infinito e imposibilita obtener datos finitos), si intentamos convertir un rango decimal a un arreglo nos va a devolver un error, por suerte si se pueden utilizar otros métodos determinísticos como include? o member?

 

irb(main):088:0> (1.1..1.4).member? 1.3

=> true

irb(main):089:0> (1.1..1.4).first

=> 1.1

irb(main):091:0> (1.1..1.4).max

=> 1.4

irb(main):092:0> (1.1..1.4).min

=> 1.1

 

Hay que notar que si el primer valor del rango es un entero y el segundo es un decimal, todo el rango se convierte en entero, por ejemplo:

 

irb(main):082:0> (1..4.4).to_a

=> [1, 2, 3, 4]

irb(main):097:0> (1..4.6).to_a

=> [1, 2, 3, 4]

 

El valor decimal del ultimo dato del rango no es redondeado sino que es truncado (osea no se toma en cuenta el valor decimal, por lo que 4.4 y 4.6 quedan finalmente como un simple 4)

 

Otro detalle a considerar es que los valores de los rangos tienen que ser del mismo tipo, si pongo un numero y una letra, el rango no se crea, otra forma de crear el rango es:

 

irb(main):099:0> Range.new 2,7

=> 2..7

irb(main):100:0> rango = (-1..3)

=> -1..3

irb(main):102:0> rango = -1..3

=> -1..3

irb(main):103:0> rango=-1..3

=> -1..3

 

Por suerte en esta asignacion no es trivial y podemos prescindir de los paréntesis.

 

Los rangos tambien pueden elaborarse de otros tipos de objetos pero estos tienen que ser compatibles (por ejemplo aquellos que deriven de la clase Time), en sí un rango nos abrevia mucho contar con valores sin tener que declararlos todos.

 

Y bien, hemos avanzado con este sencillo capitulo 14 y continuaremos con el capitulo 15, por favor dudas y comentarios pueden hacerlo si ningún tipo de restriccion, si desean agradecer también comenten.

Compartir este post
Repost0
4 febrero 2014 2 04 /02 /febrero /2014 09:01

Continuamos despúes de un largo tiempo con los tutororiales, en esta ocación tenemos los arreglos o matrices, que nos permiten agrupar distintos datos para luego acceder facilmente a ellos, en Ruby es muy facil.

 

Sintaxis:

 

[ valor1 , valor2 , valor3 ]

 

Practicamente tenemos que colocar entre 2 corchetes " [ " y " ] " todos los valores que queramos, estos valores (que pueden ser números, letras o cualquier objeto) deben estar separados por comas, no necesariamente todos los valores tienen que ser del mismo tipo, se pueden mezclar y también una matriz es un objeto de la clase Array.

 

Por ejemplo un arreglo en el irb:

 

irb(main):001:0> [1,3.6,"algo"]

=> [1, 3.6, "algo"]

 

Nos devuelve que ha reconocido la matriz, ahora podemos almacenarlo en una variable:

 

irb(main):002:0> arreglo = [1,3.6,'algo']

=> [1, 3.6, "algo"]

irb(main):003:0> arreglo.count

=> 3

 

Como podemos observar arreglo ha almacenado los 3 valores, el 1, el 3.6 y la palabra algo, ahora ya que arreglo es un objeto matriz, entonces tiene diversas propiedades y métodos, entre ellas tiene el método count, que nos cuenta cuantos datos tienen en su interior.

 

Colocando y obteniendo valores de la matriz:

 

Bueno ahora tener un arreglo nos sirve mucho y debemos poder trabajar con él, por ello vamos a obtener los valores:

 

First y last

 

Nos sirven para acceder al primer y ultimo valor

 

irb(main):004:0> arreglo.first

=> 1

irb(main):005:0> arreglo.last

=> "algo"

 

hemos usado la propiedad first que nos devuelve el primer valor "1" y luego hemos usadlo la propiedad last que nos devuelve el segundo valor "algo", ahora vamos a hacer algunas cosas mas con el first y el last:

 

irb(main):010:0> arreglo.first 2

=> [1, 3.6]

irb(main):011:0> arreglo.last 2

=> [3.6, "algo"]

irb(main):012:0> arreglo.first(2).last

=> 3.6

irb(main):013:0> arreglo.last(2).first

=> 3.6

 

En la línea 10, hemos usado el first 2, quiere decir que nos va a traer los 2 primeros valores, pero ya los trae agrupados en una matriz y esta contiene los 2 primeros valores solicitados, en la siguiente linea 11, usamos el last 2 que hace lo mismo, solo que contiene los 2 últimos valores, en la tercera línea tenemos un caso interesante; en ves de llamar a first 2, usamos los parentesis first(2), esto lo hacemos para evitar tener un caso trivial, en ruby el uso de parentesis es opcional siempre y cuando no sea trivial, (porque si ponemos first 2.last, lo que entiende Ruby es que del numero 2 va a tratar de utilizar el metodo last y como no lo tiene va a dar un error), entonces ya que el first(2) devuelve los 2 primeros valores, le indicamos que de esos 2 valores saque el último valor, que sería 3.6; en la siguiente linea 13, es lo mismo pero empezando desde el ultimo, sacando los 2 ultimos valores y luego tomando el primero de esos 2 ultimos valores, que volvería a ser 3.6, en otras palabras hemos sacado el segundo y el penúltimo valor de una forma muy facil.

 

Obteniendo un valor específico con índice

 

Un aspecto importante de un arreglo o matriz es que todos los datos tienen asociado un número de orden, que empieza desde 0, a ese número se le conoce también como índice, entonces podemos obtener cada valor de forma unitaria indicando el índice:

 

irb(main):020:0> arreglo[0]

=> 1

irb(main):021:0> arreglo[1]

=> 3.6

irb(main):022:0> arreglo[2]

=> "algo"

 

Como se puede ver, para acceder por el número de índice se debe colocar el número entre corchetes " [ " y " ] " con ello nos devuelve el valor de forma muy específica, si le ponemos un índice que no esta en el rango nos va a devolver nil:

 

irb(main):023:0> arreglo[3]

=> nil

 

Tambien podemos acceder desde los ultimos valores, colocando un valor negativo en el índice empezando desde el -1.

 

irb(main):015:0> arreglo[-1]

=> "algo"

irb(main):016:0> arreglo[-2]

=> 3.6

irb(main):024:0> arreglo[-3]

=> 1

irb(main):025:0> arreglo[-4]

=> nil

 

Al igual que en la forma positiva, si nos pasamos del rango nos devolverá un nil.

 

Preguntando por datos

 

Bueno ahora hay que consultar si algun dato se encuentra en la matriz, para ello podemos usar el método member? o include? (ambos funcionan igual)

 

irb(main):078:0> arreglo.member? "algo"

=> true

irb(main):079:0> arreglo.include? "algo"

=> true

 

Si el dato esta en el arreglo nos devolverá un true de lo contrario false, también es posible preguntar en que número de índice se encuentra determinado dato:

 

irb(main):080:0> arreglo.find_index "algo"

=> 2

irb(main):081:0> arreglo.find_index "algos"

=> nil

 

El método find_index hace ese trabajo y nos retorna el valor del dato si es que lo encuentra, en caso contrario nos devolverá nil.

 

Agregando datos

 

Agregar un dato en una matriz es bastante sencillo, se puede utilizar el operador << que agrega un dato a la matriz

 

irb(main):098:0> arreglo << :adicional

=> [1, 3.6, "algo", :adicional]

 

Como vemos hemos agregado el símbolo :adicional y se encuentra al final del arreglo, tambien podemos agregar otro elemento como una matriz por ejemplo:

 

arreglo = arreglo + [2]  que es lo mismo que arreglo += [2]

 

irb(main):105:0> arreglo += [2]

=> [1, 3.6, "algo", :adicional, 2]

 

Y ya ha agregado el arreglo (que puede tambien tener mas elementos) a la matriz, otra forma es conociendo el indice:

 

irb(main):106:0> arreglo[5]=true

=> true

irb(main):107:0> arreglo

=> [1, 3.6, "algo", :adicional, 2, true]

 

Hemos agregado el valor boolean "true" al final, indicandole explicitamente el número, tambien podemos usar una variable de la siguiente manera

 

irb(main):111:0> arreglo[arreglo.count]=false

=> false

irb(main):112:0> arreglo

=> [1, 3.6, "algo", :adicional, 2, true, false]

 

Y agregamos el "false" tambien dentro del arreglo, otra forma:

 

irb(main):221:0> arreglo.push 3

=> [1, 3.6, :adicional, 2, false, 3]

 

Agrega el valor 3 al final del arreglo, también se puede:

 

irb(main):222:0> arreglo.unshift :otro

=> [:otro, 1, 3.6, :adicional, 2, false, 3]

 

Se ha agregado el simbolo :otro al inicio de todo el arreglo

 

Eliminando datos

 

Podemos eliminar los datos de la matriz de forma sencilla:

 

irb(main):107:0> arreglo

=> [1, 3.6, "algo", :adicional, 2, true, false]

irb(main):113:0> arreglo.delete "algo"

=> "algo"

irb(main):114:0> arreglo

=> [1, 3.6, :adicional, 2, true, false]

 

El método delete recibió la palabra "algo" y en consecuencia ha eliminado el dato "algo" (si hubieran 2 palabras "algo" también las eliminaría a las 2), otra forma es:

 

irb(main):114:0> arreglo

=> [1, 3.6, :adicional, 2, true, false]

irb(main):115:0> arreglo.delete_at 4

=> true

irb(main):116:0> arreglo

=> [1, 3.6, :adicional, 2, false]

 

Ha eliminado el dato que ocupaba la posición 4 del índice, otra forma también es:

 

irb(main):223:0> arreglo.pop

=> 3

irb(main):224:0> arreglo

=> [:otro, 1, 3.6, :adicional, 2, false]

 

Donde el método pop elimina el último dato del arreglo, una forma más también:

 

irb(main):225:0> arreglo.shift

=> :otro

irb(main):226:0> arreglo

=> [1, 3.6, :adicional, 2, false]

 

Donde se elimina el primer valor del arreglo, otra forma aritmética.

 

irb(main):255:0> arreglo -= [3.6]

=> [1, :adicional, 2, false]

 

En las formas aritméticas de eliminación se debe considerar que el valor debe estar como un tipo arreglo, es decir, entre corchetes " [ " y " ] " y en el ejemplo es la versión resumida de arreglo = arreglo - [3.6]

 

Actualizando datos

 

Una forma de actualizar los datos es conociendo el índice y se reemplaza los valores

 

irb(main):241:0> arreglo

=> [1, 3.6, :adicional, 2, false]

irb(main):246:0> arreglo[3]

=> 2

irb(main):247:0> arreglo[3]=9

=> 9

irb(main):248:0> arreglo

=> [1, 3.6, :adicional, 9, false]

 

De esta manera se está cambiando el valor "2" por el valor "9", seleccionado el índice 3, otra forma sería introduciendo el índice como variable:

 

irb(main):248:0> arreglo

=> [1, 3.6, :adicional, 9, false]

irb(main):249:0> arreglo[arreglo.find_index :adicional] = "nuevo"

=> "nuevo"

irb(main):250:0> arreglo

=> [1, 3.6, "nuevo", 9, false]

 

Se cambió el símbolo :adicional por la palabra "nuevo"

 

Algunas operaciones con las matrices

 

Se puede por ejemplo invertir las matrices,rotar, etc.

 

irb(main):257:0> arreglo

=> [1, :adicional, 2, false]

irb(main):258:0> arreglo.reverse

=> [false, 2, :adicional, 1]

irb(main):260:0> arreglo.rotate

=> [:adicional, 2, false, 1]

irb(main):261:0> arreglo.rotate 2

=> [2, false, 1, :adicional]

irb(main):268:0> arreglo

=> [1, :adicional, 2, false]

 

Los arreglos, matrices, arrays o como quiera llamárseles, son muy fáciles de manejar en Ruby, obviamente existen muchos más métodos y características pero se mencionan las más comunes para que sea más facil introducirse en este mundo Ruby.

 

Bueno hemos avanzado con el capitulo 13 continuaremos con el capitulo 14, por favor dudas y comentarios pueden hacerlo si ningún tipo de restriccion, si desean agradecer también comenten.

Compartir este post
Repost0
4 julio 2012 3 04 /07 /julio /2012 00:26

Bueno ya hemos llegado a tratar con objetos, pero vamos a continuar expandiendo un poco mas sobre este lenguaje poco a poco.

 

Parámetros

 

En Ruby, un parámetro es una variable que se recibe en una funcion o método, por ejemplo, una funcion que retorna el parametro que se ha ingresado:

 

irb(main):103:0> def decir(algo)

irb(main):104:1>  return algo

irb(main):105:1> end

=> nil

irb(main):106:0> decir(:algo)

=> :algo

irb(main):107:0> decir("algo")

=> "algo"

 

Ahora la misma funcion pero un poco mas resumida (sin parentesis ni return)

 

irb(main):108:0> def decir algo

irb(main):109:1>  algo

irb(main):110:1> end

=> nil

irb(main):111:0> decir :algo

=> :algo

irb(main):112:0> decir "algo"

=> "algo"

 

Como habíamos dicho anteriormente, en Ruby los parentesis son opcionales, el return tambien es opcional, esto es porque Ruby trata de que el código sea pequeño siempre.

 

Ahora para ingresar mas parámetros se puede hacer colocando una coma, por ejemplo crearemos la funcion suma para que soporte tres parametros y los sume:

 

irb(main):141:0> def suma primero, segundo, tercero

irb(main):142:1>   primero+segundo+tercero

irb(main):143:1> end

=> nil

irb(main):144:0> suma 2, 3, 4

=> 9

 

Bueno tambien se puede tener un parametro por defecto, colocando el caracter de igual "=" y colocando algun valor, ese valor se colocará automaticamente si es que no se asigna ningun valor, por ejemplo:

 

irb(main):150:0> def pais nombre="peru"

irb(main):151:1>  nombre

irb(main):152:1> end

=> nil

irb(main):153:0> pais "cuba"

=> "cuba"

irb(main):154:0> pais

=> "peru"

 

Muy bien, luego de esta pequeña instroducción de parametros, ahora seguimos con las clase Jueguete y agregaremos su constructor

 

Constructor

 

Un constructor, al igual que otros lenguajes de POO, soporta recibir parametros cuando se crea un nuevo objeto, para ello se debe definir el metodo initialize, Ruby identifica el nombre initialize y entiende que este metodo esta reservado para definir constructores, entonces lo utilizaremos cuando creamos un nuevo jueguete, podemos indicar que marca es, para ello modificaremos la clase Juguete:

 

irb(main):155:0> class Juguete

irb(main):156:1>  def initialize marca="Acme"

irb(main):157:2>   @marca=marca

irb(main):158:2>  end

irb(main):159:1> end

=> nil

 

irb(main):162:0> caballito = Juguete.new

=> #<Juguete:0x2fd5d00 @marca="Acme">

 

irb(main):164:0> megatron = Juguete.new "Bandai"

=> #<Juguete:0x3154770 @marca="Bandai">

 

irb(main):165:0> caballito.marca

=> "Acme"

irb(main):166:0> megatron.marca

=> "Bandai"

 

Como se ve en el ejemplo, se ha creado un juguete "caballito" y como le definimos ninguna marca en la creacion, por defecto le puso "Acme", ahora en el siguiente objeto "megatron" si le pusimos una marca "Bandai" al momento de su creacion, por lo tanto su marca que nos muestra es "Bandai"

 

Bueno hasta aqui terminamos con el capitulo 12 continuaremos con el capitulo 13, poco a poco se avanza bastante, por favor dudas y comentarios pueden hacerlo sin restricciones.

Compartir este post
Repost0
28 junio 2012 4 28 /06 /junio /2012 01:22

Este capitulo es la continuación del tema 10, e incluso seguimos utilizando los ejemplos anteriores donde habíamos creado la clase Juguete y hemos creado 2 objetos, un soldadito y un trencito.

 

Propiedades

 

En Ruby, al igual que en la mayoría de lenguajes de programación orientado a objetos, una clase tiene propiedades, es decir, se definen variables que "viven" dentro de cada objeto creado.

 

Nuestros objetos "soldadito" y "trencito" no tienen ninguna propiedad, para que un objeto tenga propiedad se tiene que definir en la clase, en este caso vamos a definir una propiedad llamada "marca" en la clase "Juguete"

 

irb(main):036:0> class Juguete

irb(main):037:1>  @marca

irb(main):038:1> end

=> nil

 

Muy bien, las variables de instancia se definen con una "@" como prefijo, en este caso le hemos agregado a la clase "Juguete" una propiedad llamada @marca, esta variable de instancia viene a ser la propiedad.

 

Y algo adicional, magicamente los objetos "soldadito" y "trencito" ya tienen la propiedad @marca, esto es una característica de Ruby, pero la mala noticia es que lo tienen "adentro", es decir, no podemos acceder a esa variable porque es privada, para ello necesitamos crear una forma de acceder o mejor dicho, "una forma de comunicacion" con el objeto, y a eso se le llama metodos.

 

Metodos

 

En las clases de Ruby pueden definirse métodos, que son una especie de funciones o definiciones que hacen algo, ahora en la POO cuando una funcion permite al objeto un mecanismo de comunicacion ya no se le dice funcion sino se le dice método, por ejemplo vamos a agregar un método que devuelva de que país son los juguetes, para ello modificamos la clase:

 

irb(main):059:0> class Juguete

irb(main):060:1>  def pais

irb(main):061:2>   return "Peru" #En Ruby la palabra "return" no es necesario siempre que la sintaxis no sea trivial.

irb(main):062:2>  end

irb(main):063:1> end

=> nil

 

Al igual como hicimos para definir la propiedad @marca, hemos modificado nuevamente la clase Juguete y hemos agregado un metodo (o funcion) llamado pais, los métodos se definen con la palabra "def", y automagicamente "trencito" y "soldadito" ya cuentan con ese método, para llamarlo solo basta poner el punto "." y el nombre del metodo.

 

irb(main):064:0> soldadito.pais

=> "Peru"

 

Ahora este método simplemente nos muestra la palabra "Peru", si quisieramos modificarlo (para que pais ya no se llame "Peru" sino otro nombre), tenemos que agregar otro metodo más que nos permita cambiar el país.

 

Pero recordamos que soldadito tiene una propiedad llamada @marca pero que no tenemos como acceder, podríamos construir un metodo similiar al "def pais" pero existe un camino mas facil (y menos código)

 

irb(main):065:0> class Juguete

irb(main):066:1>  attr_accessor :marca

irb(main):067:1> end

=> nil

 

En una sola linea (la 066) hemos definido no solo 1 metodo, sino 2 metodos de lectura y escritura de la variable de instancia @marca (mediante el simbolo :marca el attr_accessor reconoce @marca y ademas crea los metodos marca), ahora automagicamente ya lo podemos usar en nuestros objetos.

 

irb(main):080:0> soldadito.marca="Acme"

=> "Acme"

irb(main):081:0> soldadito.marca

=> "Acme"

 

Como vemos, ya tenemos los metodos para utilizar nuestra variable de instancia @marca.

 

El "attr_accessor" utiliza la "metaprogramacion" que en cristiano, lo que hace es crear los metodos automágicamente en tiempo de ejecucion (es decir cuando ya se esta usando el programa).

 

Tambien estamos viendo que la codificacion es bien reducida en Ruby, por lo que nos ayuda a entender más fácil y rápido el codigo fuente.

 

Bueno terminamos con este tema 11, continaremos con el tema 12, no se olviden de exponer sus dudas en la seccion de comentarios lineas abajo y no necesitas registrarte.

Compartir este post
Repost0
27 junio 2012 3 27 /06 /junio /2012 00:18

Luego de haberle dado un vistazo al lenguaje de programación Ruby, creo que es suficiente introducción para empezar realmente a entender en forma mas basica Ruby.

 

POO

 

Como la gran mayoría de programadores conoce, la POO (Programación Orientada a Objetos) es un pilar extremadamente básico de Ruby, para los que no conocen qué es la POO no se preocupen, con Ruby es muy natural empezar a programar siguiendo los lineamientos de POO.

 

Para empezar, definiremos con ejemplos y analogías que es una clase y sus propiedades, pongan atención ya que es demasiado importante.

 

Clase

 

La clase simplemente sirve para definir nuevos objetos, pongo un ejemplo práctico:

 

Imaginen un trencito de plástico, si nos preguntan "¿que clase de objeto es eso?" nosotros simplemente le responderíamos "es un juguete".

 

Ahora imaginen un soldadito de madera, si nos preguntan "¿que clase de objeto es eso?" nosotros simplemente le responderíamos "es un juguete".

 

Entonces deducimos por razones obvias que en el ejemplo, la "clase" vendría a ser "juguete" y por lo tanto, podemos decir "La clase juguete" que en ruby simplemente pondriamos:

 

class Juguete

 

# Aqui va todo el codigo que define esta clase Jueguete

 

end

 

Donde class viene a ser "Clase" y hemos creado una clase llamada "Juguete", end sirve para indicar que hasta ahí termina la definicion de la clase, es decir si ponemos class siempre tiene que haber un end (para los que ya han programado antes: end en sí, es la terminacion de la sintaxis de class).

 

El nombre de la clase, debe ser escrito en capital (osea la primera letra en mayúscula) como en el ejemplo "Juguete"

 

Ahora vamos a utilizar el IRB y definir esta clase "Juguete" en Ruby de una vez:

 

irb(main):026:0> class Juguete

irb(main):027:1> end

=> nil

irb(main):028:0> Juguete

=> Juguete

 

Como pueden observar, la linea 26 y 27 ha definido una clase llamada Juguete, en la linea 28, cuando ponemos el nombre de la clase creada, el IRB nos responde (en consecuencia) la clase Juguete.

 

Utilizar la clase: Instancias

 

Como se imaginaran, la clase ya esta creada, ahora deseamos utilizarlo para crear a al soldadito de madera y al trencito de plástico.

 

trencito = Juguete.new    # se leería como "trencito" es un "nuevo" objeto de la clase "Juguete"

soldadito = Juguete.new

 

En este caso, se dice que trencito y soldadito son "instancias" de la clase "Juguete", ademas que ahora trencito y soldadito son objetos (y por supuesto tambien son variables que almacenan un objeto de la clase "Juguete").

 

En el IRB sería:

 

irb(main):030:0> trencito = Juguete.new

=> #<Juguete:0x2f9eda0>

 

irb(main):031:0> soldadito = Juguete.new

=> #<Juguete:0x26b1970>

 

Como se puede observar, new sirve para indicar que la clase "Juguete" cree un nuevo objeto (un nuevo jueguete) y para ello lo debe almacenar en algun lugar, entonces, trencito y soldadito son variables que almacenan ese "nuevo juguete", esta acción les hace merecedor de definirlos como que "trencito y soldadito" son objetos.

 

Ademas, el IRB responde efectivamente que tanto trencito y soldadito es un objeto Juguete, y adicionalmente muestra un identificador o "id" de cada uno: 0x2f9eda0 para trencito y 0x26b1970 para soldadito, esto es porque cada "nuevo juguete" nace con un "id" propio por si "instanciamos" (o creamos) varios "trencitos" o varios "soldaditos" y que estos no se reemplacen entre si (o se "chanquen").

 

Muy bien, espero que haya sido de mucha utilidad y terminamos con el tema 10, ahora vamos a seguir con el tema 11 que es practicamente la continuacion y esta muy interesante e importante, por favor no se queden con las dudas y comenten.

Compartir este post
Repost0
26 junio 2012 2 26 /06 /junio /2012 23:40

Bueno estos valores logicos son sencillamente 2, verdadero y falso, pero en realidad ya concemos que son objetos, ademas existe un valor nulo llamado nil que se comporta como falso, por lo tanto tienen mas propiedades que veremos mas adelante.

 

Valores

 

Los valores de verdad y mentira contienen su propio valor llamado true y false respectivamente, para los valores nulos o mejor dicho "sin valor" se conoce como nil, y en realidad si tiene un valor llamado y se llama nil, aqui unos ejemplos comparativos.

 

irb(main):001:0> true

=> true

irb(main):002:0> false

=> false

irb(main):003:0> true == true

=> true

irb(main):004:0> false == false

=> true

irb(main):005:0> nil

=> nil

irb(main):006:0> nil == true

=> false

irb(main):007:0> nil == false

=> false

irb(main):008:0> nil == nil

=> true

 

Para utilizar en alguna logica valores de "si" o "no" se debería utilizar true y false.

 

Para utilizar nil, se comporta de manera diferente y aunque se puede utilizar su valor, no garantiza que los demas objetos de ruby lo almacenen o utilicen como valor, el nil puede llamar a excepciones, limpiar variables y muchas cosas mas.

 

Algunos ejemplos de comparaciones: (el operador && significa and y el operador || significa or)

 

irb(main):011:0> nil && false   # (tambien se podria utilizar nil and false)

=> nil

irb(main):012:0> false && nil

=> false

irb(main):013:0> true || false  # (tambien se podria utilizar true or false)

=> true

irb(main):014:0> nil || false

=> false

irb(main):015:0> false || nil

=> nil

 

En Ruby todo valor es true, a excepcion de false y nil, incluso el 0 es un valor true asi que hay que tener cuidado cuando se utilize en condiciones el valor 0.

 

Bueno terminamos con este capitulo 9 ahora puedes pasar al capitulo 10, como dato adicional les comento que no me gusta dejar tareas ni nada por el estilo, mi intencion es que de un vistazo ya tengan el conocimiento y quizas lo prueben en su consola irb, que creo que es mucho mas efectivo que andar de tarea en tarea. SI tienen comentarios click en escribir un comentario en la parte inferior.

Compartir este post
Repost0
17 junio 2012 7 17 /06 /junio /2012 22:59

Okey, estamos ya avanzando un poco en el mundo de Ruby, hemos llegado a un punto muy interesante sobre las cadenas, son parecidos a los simbolos pero en realidad son fundamentalmente parte de los simbolos.

 

Cadenas de caracteres

 

En Ruby las cadenas de caracteres son un conjunto de caracteres pero estos no se almacenan sino son una simple especificación, al igual que los números, es decir que para conservar el valor es necesario una variable, que a difierencia de los simbolos, los simbolos no necesitan una variable para conservar su valor.

 

Las cadenas se definen por las comillas simples ´ y las comillas dobles  "

 

Algunos ejemplos de cadena de caracteres

 

 

irb(main):037:0> 'cielo'

=> "cielo"

irb(main):038:0> "tierra"

=> "tierra"

 

 

Tambien es posible hacer comparaciones en las cadenas de caracteres que tienen una comilla o comilla doble

 

 

irb(main):039:0> 'cielo' == 'cielo'

=> true

irb(main):040:0> 'cielo' == 'Cielo'

=> false

irb(main):041:0> 'cielo' == "Cielo"

=> false

irb(main):042:0> 'cielo' == "cielo"

=> true

 

 

Las cadenas de caracteres son tambien objetos, asi que tambien tienen varias ventajas.

 

Tambien una cadena es un arreglo, por lo tanto podemos acceder a un caracter especifico

 

irb(main):001:0> "tierra"[2]

=> "e"

irb(main):002:0> 'tierra'[5]

=> "a"

 

Bueno hasta ahora acabamos con el capitulo 8, ahora el siguiente es el 9, se que las cadenas tienen mucho mas caracteristicas pero en los siguientes capitulos vamos a profundizar en el tema, comenten libremente todas sus dudas seran absueltas.

Compartir este post
Repost0

Presentación

  • : El blog de Daniel A. Nuñez C.
  • : Un blog sobre tecnologías y futuro, también sobre lenguaje de programación Ruby y más.
  • Contacto

Perfil

  • Daniel A. Nuñez C.
  • Ingeniero de Sistemas
  • Ingeniero de Sistemas

Donaciones/Donations

Por favor considera realizar una donación

Please make a donation

btn_donateCC_LG.png

Buscar Tema En Este Blog

Archivos